package com.code.soulqlexpress.func;

import com.ql.util.express.ArraySwap;
import com.ql.util.express.InstructionSetContext;
import com.ql.util.express.OperateData;
import com.ql.util.express.OperatorOfNumber;
import com.ql.util.express.instruction.op.OperatorBase;
import org.apache.commons.lang3.StringUtils;

/**
 * 表达式函数decode
 * <p>参数数量必须大于2使用方式如</p>
 * <li>{a:0}, decode(a,1) result is null</li>
 * <li>{a:0}, decode(a,1,0,0,1) result is 1</li>
 * <li>{a:1}, decode(a,1,0,0,1) result is 0</li>
 * <li>带有默认值的情况{a:3}, decode(a,1,0,0,1,2) result is 2</li>
 *
 * @Author:jdy
 * @Date:2020/3/16
 * @Content:
 */
public class DecodeOperator extends OperatorBase {

    private static final long serialVersionUID = 7971994136478570932L;
    private static int MIN_PARAM = 2;

    @Override
    public OperateData executeInner(InstructionSetContext instructionSetContext, ArraySwap arraySwap) throws Exception {
        //第一个参数
        final OperateData operateData = arraySwap.get(0);
        final Object object = operateData.getObject(instructionSetContext);
        if (object == null) {
            return null;
        }
        int length = arraySwap.length;
        //参数必须大于2
        if (length <= MIN_PARAM) {
            return null;
        }
        OperateData compareData, resultData;
        for (int i = 1; i < length; i++) {
            compareData = arraySwap.get(i);
            if (i == length - 1) {
                return compareData;
            }
            resultData = arraySwap.get(++i);
            if (object instanceof String) {
                final boolean equals = StringUtils.equals(object.toString(),
                        compareData.getObjectInner(instructionSetContext).toString());
                if (equals) {
                    return resultData;
                }
            } else {
                final int compareResult = OperatorOfNumber.compareNumber(Double.parseDouble(object.toString()),
                        Double.parseDouble(compareData.getObjectInner(instructionSetContext).toString()));
                if (compareResult == 0) {
                    return resultData;
                }
            }
        }
        return null;
    }
}
